package com.yanqu.road.server.cmd.player;

import com.yanqu.road.entity.enums.*;
import com.yanqu.road.entity.servercenter.ServerGroup;
import com.yanqu.road.entity.union.cross.CrossUnionMember;
import com.yanqu.road.logic.bussiness.player.UserAttributeBussiness;
import com.yanqu.road.logic.bussiness.player.UserBussiness;
import com.yanqu.road.logic.bussiness.player.UserInteractiveBussiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.entity.interactive.InteractiveRecord;
import com.yanqu.road.entity.interactive.UserInteractive;
import com.yanqu.road.entity.player.*;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.pb.player.PlayerProto;
import com.yanqu.road.server.GameServer;
import com.yanqu.road.server.cmd.base.AbstractCommand;
import com.yanqu.road.server.gameplayer.GamePlayer;
import com.yanqu.road.server.gameplayer.module.player.*;
import com.yanqu.road.server.gameplayer.module.xiaomian.XiaoMianModule;
import com.yanqu.road.server.manger.ServerGroupMgr;
import com.yanqu.road.server.manger.config.InteractiveMgr;
import com.yanqu.road.server.manger.player.UserMgr;
import com.yanqu.road.server.manger.player.GamePlayerMgr;
import com.yanqu.road.server.manger.rank.RankMgr;
import com.yanqu.road.server.manger.union.CrossUnionMgr;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.server.command.Cmd;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigInteger;
import java.util.Map;

@Cmd(code = Protocol.S_GIVE_LIKE, desc = "点赞")
public class GiveLikeCmd extends AbstractCommand {

	private int type;
	private long likeUserId;

	private int heartCount;
	private UserInfo likeUserInfo;
	private BigInteger effectValue = BigInteger.ZERO;
	private long likeServerId;
	private boolean needResponse;

	@Override
	public boolean parseData(YanQuMessage packet) throws Exception {
		PlayerProto.GiveLikeReqMsg reqMsg = PlayerProto.GiveLikeReqMsg.parseFrom(packet.getBytes());
		likeUserId = reqMsg.getUserId();
		type = reqMsg.getType();
		likeServerId = reqMsg.getServerId();
		return true;
	}

	@Override
	public void execute(GamePlayer player, YanQuMessage packet) throws Exception {
		if(0 == likeServerId){
			likeServerId = GameServer.getInstance().getServerId();
		}
		if(likeServerId == GameServer.getInstance().getServerId()){//本服点赞
			localServerLogic(player);
		}else {
			crossServerLogic(player);
		}
	}

	private void localServerLogic(GamePlayer player){
		needResponse = true;
		likeUserInfo = UserMgr.getUserInfo(likeUserId);
		if(null == likeUserInfo){
			ret = GameErrorCode.E_USER_NO_FOUND;
			return;
		}

		// 先恢复下点赞值，否则会有误差
		UserMgr.autoRecoverHeart(likeUserInfo);

		player.notifyListener(eGamePlayerEventType.GiveLikeTimes.getValue(), 1);
		UserInteractive userInteractive = player.getModule(InteractiveModule.class).getUserInteractive();
		if(userInteractive.hasLikeUserId(likeUserId)){
			ret = GameErrorCode.E_HAS_GIVE_LIKE;
			return;
		}
		int limitValue = InteractiveMgr.getBeLikeLimit(likeUserId);
		GamePlayer likePlayer = GamePlayerMgr.getOnlinePlayer(likeUserId);
		synchronized (likeUserInfo){
			heartCount = likeUserInfo.getHeartCount();
			if(heartCount >= limitValue){
				ret = GameErrorCode.E_PLAYER_CURRENT_LIKE_LIMIT;
				return;
			}
			if(0 == type) {
				if (userInteractive.getLikeCount() >= GameConfig.GIVE_LIKE_MAX_COUNT) {
					ret = GameErrorCode.E_OVER_GIVE_LIKE_TIMES;
					return;
				}
			}else if(1 == type) {
				if (userInteractive.getLikeCount() >= GameConfig.GIVE_LIKE_MAX_COUNT) {//没有点赞次数了
					if(!player.getModule(CurrencyModule.class).removeCurrency(new Property(GameConfig.GAME_ITEM_LIKE, BigInteger.ONE),
							eLogMoneyType.System, eLogMoneyType.GiveLike)){
						ret = GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
						return;
					}
				}
			}else {
				ret = GameErrorCode.E_GIVE_LIKE_TYPE_ERROR;
				return;
			}
			heartCount++;
			likeUserInfo.setHeartCount(heartCount);
			effectValue = UserMgr.getHeartEffectEarnSpeed(likeUserInfo.getBaseEarnSpeed());

			if(null != likePlayer){
				likePlayer.getModule(AttributeModule.class).syncAttribute(ePlayerAttrType.HeartCount);
				//likePlayer.getModule(EarnSpeedModule.class).scheduleAddSilver();
			}else {
				likeUserInfo.setEarnSpeed(likeUserInfo.getEarnSpeed().add(effectValue));
				//赚速榜
				RankMgr.changeUserRank(eBigRankType.Normal.getValue(), likeUserInfo.getUserId(), likeUserInfo.getEarnSpeed(), eRankType.EarnSpeed.getValue(), "");
			}
		}
		if(null != likePlayer) {
			//likePlayer.getModule(AttributeModule.class).syncAttribute(ePlayerAttrType.HeartCount);
			likePlayer.getModule(EarnSpeedModule.class).scheduleAddSilver();
		}
		if(1 == heartCount){
			likeUserInfo.setLastHeartRecoverTime(System.currentTimeMillis() / 1000);
			if(null == likePlayer){
				UserBussiness.updateLastHeartRecoverTimeAndEarnSpeed(likeUserId, heartCount, likeUserInfo.getLastHeartRecoverTime(), likeUserInfo.getEarnSpeed());
			}
		}else {
			if(null == likePlayer){
				UserBussiness.updateHeartCountAndEarnSpeed(likeUserId, heartCount, likeUserInfo.getEarnSpeed());
			}
		}
		if(null == likePlayer){
			UserAttributeBussiness.updateAddUserAttribute(likeUserId, ePlayerAttrType.TotalBeGiveLikeTimes, 1);
		}else {
			AttributeModule likeAttributeModule = likePlayer.getModule(AttributeModule.class);
			likeAttributeModule.addAttribute(ePlayerAttrType.TotalBeGiveLikeTimes, 1);
			likePlayer.notifyListener(eGamePlayerEventType.TotalBeGiveLikeTimes.getValue(), likeAttributeModule.getAttribute(ePlayerAttrType.TotalBeGiveLikeTimes));
		}
		userInteractive.addLikeUserId(likeUserId);
		userInteractive.setTotalGiveLikeTimes(userInteractive.getTotalGiveLikeTimes() + 1);
		player.notifyListener(eGamePlayerEventType.GiveLikeTotalTimes.getValue(), userInteractive);
		player.notifyListener(eGamePlayerEventType.TotalGiveLikeTime.getValue(), 1);
		//平台数据加一下
		player.getModule(XiaoMianModule.class).addGiveLikeTimes(1);

		player.getModule(InteractiveModule.class).syncUserInteractive();
		InteractiveRecord interactiveRecord = UserMgr.initInteractiveRecord(likeUserId, eInteractiveType.giveLike.getValue(),
				player.getUserId(), UserMgr.getUserBaseInfo(player.getUserId(), GameServer.getInstance().getServerId()));
		if(null != likePlayer) {
			likePlayer.getModule(InteractiveModule.class).addInteractiveRecord(interactiveRecord, effectValue);
		}else {
			UserInteractiveBussiness.addInteractiveRecord(interactiveRecord);
		}
	}

	private void crossServerLogic(GamePlayer player){
		needResponse = true;
		boolean isPreReduce = false;
		String unionUid = player.getUserInfo().getUnionUid();
		boolean canLikeOther = false;
		//如果有商会 判断这个人是不是在商会里
		if(!StringUtils.isNullOrEmpty(unionUid)){
			Map<Long, CrossUnionMember> memberMap = CrossUnionMgr.getUnionMemberMap(unionUid);
			if(memberMap.containsKey(likeUserId)){
				canLikeOther = true;
			}
		}
		//如果不是商会点赞 去判断聊天跨服
		if (!canLikeOther){
			ServerGroup serverGroup = ServerGroupMgr.getServerGroupByServerId(GameServer.getInstance().getServerId());
			if (null != serverGroup && serverGroup.isCrossChat() && serverGroup.getServerList().contains(likeServerId)){
				canLikeOther = true;
			}
		}
		if (!canLikeOther){
			ret = GameErrorCode.E_CANNOT_GIVE_LIKE_NO_SAME_UNION_OR_SAME_GROUP;
			return;
		}

		player.notifyListener(eGamePlayerEventType.GiveLikeTimes.getValue(), 1);
		InteractiveModule interactiveModule = player.getModule(InteractiveModule.class);
		UserInteractive userInteractive = interactiveModule.getUserInteractive();
		if(userInteractive.hasLikeUserId(likeUserId)){
			ret = GameErrorCode.E_HAS_GIVE_LIKE;
			return;
		}
		//判断是否有在操作跨服点赞了，防止连续操作
		if(interactiveModule.isOpLikeUser(likeUserId)){
			ret = GameErrorCode.E_IS_CROSS_GIVE_LIKE_PLAYER;
			return;
		}
		if(0 == type) {
			if (userInteractive.getLikeCount() >= GameConfig.GIVE_LIKE_MAX_COUNT) {
				ret = GameErrorCode.E_OVER_GIVE_LIKE_TIMES;
				return;
			}
		}else if(1 == type) {
			if (userInteractive.getLikeCount() >= GameConfig.GIVE_LIKE_MAX_COUNT) {//没有点赞次数了
				Property consume = new Property(GameConfig.GAME_ITEM_LIKE, BigInteger.ONE);
				if(!player.getModule(CurrencyModule.class).currencyIsEnough(consume)){
					ret = GameErrorCode.E_BAG_ITEM_NO_ENOUGH;
					return;
				}
				//预扣除
				player.getModule(PreReduceModule.class).preReduce(consume);
				isPreReduce = true;
			}
		}else {
			ret = GameErrorCode.E_GIVE_LIKE_TYPE_ERROR;
			return;
		}

		interactiveModule.addOpLikeUserId(likeUserId);
		//发往跨服
		PlayerProto.CrossGiveLikeReqMsg.Builder crossMsg = PlayerProto.CrossGiveLikeReqMsg.newBuilder();
		crossMsg.setUserId(player.getUserId());
		crossMsg.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(UserMgr.getUserBaseInfo(player.getUserId(), GameServer.getInstance().getServerId())));
		crossMsg.setType(type);
		crossMsg.setLikeUserId(likeUserId);
		crossMsg.setLikeServerId(likeServerId);
		crossMsg.setIsPreReduce(isPreReduce);
		YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.C_GIVE_LIKE, crossMsg);
		GamePlayerMgr.sendPacket(player.getUserId(), pbMsg);

		needResponse = false;
	}

	@Override
	public void sendData(GamePlayer player) {
		if(needResponse) {
			PlayerProto.GiveLikeRespMsg.Builder respMsg = PlayerProto.GiveLikeRespMsg.newBuilder();
			respMsg.setRet(ret);
			if (0 == ret) {
				respMsg.setHeartCount(heartCount);
				respMsg.setEarnSpeed(likeUserInfo.getEarnSpeed().toString());
				respMsg.setEffectValue(effectValue.toString());
			}
			player.sendPacket(Protocol.U_GIVE_LIKE, respMsg);
		}
	}
}
